﻿using Caching.Config;
using StackExchange.Redis;
using System.Net;

namespace Caching.Redis;

public class RedisConnectionWrapper : IRedisConnectionWrapper
{
    private readonly object _lock = new object();
    private readonly CacheConfig _config;
    private readonly Lazy<string> _connectionString;
    private volatile ConnectionMultiplexer _connection;

    public RedisConnectionWrapper(CacheConfig cacheConfig)
    {
        _config = cacheConfig;
        _connectionString = new Lazy<string>(GetConnectionString);
    }

    /// <summary>
    /// 从配置中获取连接
    /// </summary>
    /// <returns></returns>
    protected string GetConnectionString()
    {
        return _config.RedisCachingConnectionString;
    }

    /// <summary>
    /// 获取到Redis服务器的连接
    /// </summary>
    /// <returns></returns>
    protected ConnectionMultiplexer GetConnection()
    {
        if (_connection != null && _connection.IsConnected)
        {
            Console.WriteLine("用原先的！");
            return _connection;
        }

        lock (_lock)
        {
            if (_connection != null && _connection.IsConnected)
            {
                Console.WriteLine("用原先的！");
                return _connection;
            }
            Console.WriteLine("销毁了！");

            Dispose();

            _connection = ConnectionMultiplexer.Connect(_connectionString.Value);
        }

        return _connection;
    }

    /// <summary>
    ///
    /// </summary>
    public void Dispose()
    {
        _connection?.Dispose();
    }

    /// <summary>
    /// 删除数据库的所有键
    /// </summary>
    /// <param name="db"></param>
    public void FlushDatabase(int? db = null)
    {
        var endPoints = GetEndPoints();

        foreach (var endPoint in endPoints)
        {
            GetServer(endPoint).FlushDatabase(db ?? -1);
        }
    }

    /// <summary>
    /// 获取到Redis内部数据库的交互式连接
    /// </summary>
    /// <param name="db">数据库数量;传递null以使用默认值。</param>
    /// <returns></returns>
    public IDatabase GetDatabase(int? db = null)
    {
        return GetConnection().GetDatabase(_config.DefaultDB);
    }

    /// <summary>
    /// 获取服务器上定义的所有端点
    /// </summary>
    /// <returns></returns>
    public EndPoint[] GetEndPoints()
    {
        return GetConnection().GetEndPoints();
    }

    /// <summary>
    /// 获取单个服务器的配置API
    /// </summary>
    /// <param name="endPoint"></param>
    /// <returns></returns>
    public IServer GetServer(EndPoint endPoint)
    {
        return GetConnection().GetServer(endPoint);
    }
}